#ifndef RTE_KB1276_RETAIN_KVDB_H
#define RTE_KB1276_RETAIN_KVDB_H

#include <kvdb.h>

class retain_kvdb : public mem_block {
public:
    explicit retain_kvdb(const char *fname, const char *fname2 = nullptr) {
        filename[0] = fname;
        filename[1] = fname2;
    }

    void begin(const char *name, int size) override {
        filename[0] = name;
        buf = (char *) malloc(size);
        _size = size;
        logger.info("Retain use kvdb ,size=%d", _size);
    }

    int Shutdown() override {
        // free(buf);
        return 0;
    };

    void Remove(int i) override { kvdb.remove(filename[i]); }

    int Read(u8 block, unsigned int adr, unsigned int size, void *pVoid) override {
        int sz = kvdb.get(filename[block], (char *) buf, _size, nullptr);
        memcpy(pVoid, buf + adr, size);
        return sz;
    }

    void Write(unsigned char block, unsigned int adr, void *pVoid, unsigned int size) override {
        memcpy(buf + adr, pVoid, size);
        kvdb.set(filename[block], (char *) buf, _size);
    }

    int dat_len{}, pos{};
    fdb_kv *kv = nullptr;

    int begin(byte *cmd, byte sz, uint32_t adr, uint32_t len) override {
        dat_len = *(int *) cmd;
        u8 key_len = strlen(reinterpret_cast<const char *>(&cmd[4]));
        if ((key_len + 4) > sz)
            return -1;
        kv = kvdb.open_write((const char *) (&cmd[4]), KV_BIN_VALUE);
        pos = 0;
        if (kv)
            return 4096;
        return -5;
    }

    int begin_read(byte *name, byte name_sz, uint32_t start_address, uint32_t data_len) override {
        u8 key_len = strlen(reinterpret_cast<const char *>(name));
        if ((key_len) > name_sz)
            return -1;
        kv = kvdb.open_read((const char *) (name));
        pos = 0;
        if (kv)
            return 4096;
        return -5;
    }

    int Write(byte *dat, int len) override {
        if (dat_len && (pos + len) >= dat_len) {
            return -1;
        }
        if (kv) {
            kvdb.write(kv, pos, reinterpret_cast<const char *>(dat), len);
            pos += len;
            return 0;
        }
        return -2;
    }

    const char *filename[2] = {};
    int _size{};
    char *buf{};

    const char *name() override { return "kvdb"; }
};

#endif // RTE_KB1276_RETAIN_KVDB_H
